package org.example.nt;

import cn.gmssl.jce.provider.GMJCE;
import com.aliyun.gmsse.GMProvider;
import com.aliyun.gmsse.GMSSLContextSpi;
import com.aliyun.gmsse.GMX509KeyManagerFactory;
import com.aliyun.gmsse.GMX509TrustManagerFactory;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.util.CharsetUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;

public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    private static final Provider GMJCE = new GMJCE();
    private static final Provider BC;
    static {
//        BC.put("SSLContext.TLS", GMSSLContextSpi.class.getName());
//        BC.put("KeyManagerFactory.X509",   GMX509KeyManagerFactory.class.getName());
//        BC.put("TrustManagerFactory.X509", GMX509TrustManagerFactory.class.getName());
        Security.insertProviderAt(new cn.gmssl.jce.provider.GMJCE(), 1);
        Security.insertProviderAt(new cn.gmssl.jsse.provider.GMJSSE(), 1);

        BC = Security.getProvider("BC");
    }
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        socketChannel.pipeline().addLast(createSslHandler(initSSLContext(), false));
        // 编解码
        socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
        socketChannel.pipeline().addLast(new NettyServerHandler());
    }

    private ChannelHandler createSslHandler(SSLContext sslContext, boolean needsClientAuth) {
        SSLEngine sslEngine = sslContext.createSSLEngine();
        sslEngine.setUseClientMode(false);
        if (needsClientAuth) {
            sslEngine.setNeedClientAuth(true);
        }
        return new SslHandler(sslEngine);
    }

    private SSLContext initSSLContext() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
        KeyStore ks = KeyStore.getInstance("BouncyCastle", BC);
//        KeyStore ks = KeyStore.getInstance("JKS");
        FileInputStream fileInputStream = new FileInputStream("D:\\ws\\java\\springboot-demo\\netty-demo\\sm\\sm-client.ks");
        ks.load(fileInputStream, null);
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("CM");
        kmf.init(ks, null);
        SSLContext sslContext = SSLContext.getInstance("TLS");
//        SSLContext sslContext =  SSLContexts.custom().setProvider(new GMProvider()).loadTrustMaterial(null,new HrjkTrustStrategy()).build();
        try {
            sslContext.init(kmf.getKeyManagers(), null, null);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslContext;
    }
}
